﻿/*
   Advanced Flash Engine in ActionScript 3.
   Copyright (C) 2009  Dean Gardiner, Taylor Lodge

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.winmastergames.lolgame {
	/* =============Class Imports============= */
	import com.flashdynamix.utils.SWFProfiler;
	import com.winmastergames.multiplayer.multiplayerChat;
	import com.winmastergames.screenManager.buttonHandler;
	import com.winmastergames.screenManager.buttonObject;
	import com.winmastergames.screenManager.refHelper;
	import com.winmastergames.screenManager.screenHandler;
	import com.winmastergames.screenManager.screenObject;
	import flash.media.Sound;
	import flash.system.Security;
	import com.winmastergames.rMath.Rrandom;
	import com.winmastergames.decalsystem.decalLoader;
	import flash.display.Bitmap;
	import flash.display.DisplayObjectContainer;
	import flash.display.LoaderInfo;
	import flash.display.Loader;
	import com.anotherearlymorning.PixelPerfect.*;
	import com.winmastergames.gameassets.*;
	import com.winmastergames.lolgame.enemys.*;
	import com.winmastergames.lolgame.gameUtils;
	import com.winmastergames.lolgame.consoleParser;
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.text.TextField;
	import flash.geom.Rectangle;
	import com.senocular.utils.KeyObject;
	import com.adventuresinactionscript.collisions.HitTest;
	import com.guiltfilter.utils.FramerateTracker;
	import flash.display.DisplayObject;
	import flash.display.Stage;
	import com.kongregate.as3.client.KongregateAPI;
	import com.kongregate.as3.client.events.KongregateEvent;
	import com.winmastergames.lolgame.weapons.*;
	import flash.ui.Mouse;
	import flash.utils.Timer;
	import flash.ui.Keyboard;
	import com.adventuresinactionscript.collisions.HitTest;
	import com.winmastergames.lolgame.consoleParser;
	import com.winmastergames.lolgame.pathnodeDebug;
	import flash.display.StageScaleMode;
	import com.winmastergames.configParser.mapParser;
	import com.winmastergames.lolgame.turret;
	import com.winmastergames.lolgame.engineHud;
	import com.winmastergames.multiplayer.MultiplayerClient;
	import com.winmastergames.gameassets.enemySpawner;

	/* =============Main Class============= */
	public class engine extends MovieClip {
		/* =============Public Declares============= */
		public static var maxAi = 32;
		var drawedGame:Boolean = false;
		var kongregate:KongregateAPI = new KongregateAPI(); //Main Kongregate Declare.
		var key:KeyObject; //For Handling Key Presses.
		public var fpstracker:FramerateTracker = new FramerateTracker(); //Create New Framerate Tracker.
		public static var achievementNotice_mc:achievements = new achievements();
		public var player_mc:player = new player(stage); //Create New Player.
		var playerTarget:player_ltarget = new player_ltarget();
		public static var st_playerTarget:player_ltarget;
		public var level_mc:mapDefault = new mapDefault(stage, player_mc, this, kongregate, playerTarget); //Create New Level.
		public static var st_level_mc:mapDefault; //?
		public static var st_player_mc:player;
		public var turretArray:Array = new Array(new turret(level_mc, 15, 100, true, false));
		public static var st_turretArray:Array = new Array();
		public var pickupsArray:Array = new Array(new Glock(level_mc, 999, 999, 20), new Glock(level_mc, 0, 0, 20), new USP(level_mc, 35, 35, 15), new Glock(level_mc, 30, 70, 20), new remmington870s(level_mc, 70, 50, 8)); //Create New Pickups Array.
		public var powerupsArray:Array = new Array; //Creates the powerupsArray for storing powerups
		public static var powerupsArrayRO:Array = new Array; //Static version of it so we can add powerups to it
		public static var consoleMC:console = new console(); //Creates the console variable
		public var pathNodeArray:Array = new Array(new pathnode(level_mc, 25, 25), new pathnode(level_mc, 100, 50), new pathnode(level_mc, 200, 100), new pathnode(level_mc, 100, 150));
		public static var st_pathNodeArray:Array = new Array();
		public static var pathnodeDebugMC:pathnodeDebug = new pathnodeDebug();
		public static var pickupsArrayRO:Array; //Create New Static Pickups Array.
		var Speed:Number = 3; //Speed Variable.
		var mouseActiveOnStage:Boolean = true;
		var esc:Number = 1;
		//0 = Nothing
		//1 = Left
		//2 = Right
		//3 = Top
		//4 = Bottom
		//5 = Top, Left
		var Dir:Number = 0; //Direction Variable.
		var StopDir:Number = 0; //Hit Wall Direction Variable.
		/* ===========Weapon Ammo=================== */
		public static var ammoRemaining:Number = player.weaponClipSize;
		public var ammoCount:Number = player.ammoNineMM;
		public var clipSize = player.weaponClipSize;
		/* ==========Special Root Declares========== */
		public static var myStage:Stage; //Static Stage Declare.
		public static var myRoot:DisplayObject; //Static Root Declare.
		public static var debugtextfield:String = ""; //Static Debug TextField Declare.
		public static var tempCrosshair:crosshair = new crosshair();
		//Rofl Weapon Shooting :)
		var keyC:uint = 192;
		var debugTabOpen:Boolean = false;
		var debugOpening:Boolean = false;
		var bulletArray:Array = new Array();
		public static var st_bulletArray:Array = new Array();
		var enemyArray:Array = new Array();
		public var spawnerArray:Array = new Array(new enemySpawner(level_mc, 100, -480, 100, 3), new enemySpawner(level_mc, 950, 30, 150, 5), new enemySpawner(level_mc, 86, 730, 75, 1.5), new enemySpawner(level_mc, -649, 75, 250, 10));
		public static var st_spawnerArray:Array;
		public static var st_enemyArray:Array;
		var latestError:String = "NaN";
		var countErrors:Number = 0;
		var shooting:Boolean = false;
		public static var shootingDelay:Number = 100;
		var fireTimer:Timer = new Timer(shootingDelay);
		var spawnTimer:Timer = new Timer(2500);
		public static var canFire:Boolean = true;
		var firedBullet:Boolean = false;
		public static var fireSpeed:Number = 6;
		var hbArray:Array = new Array();
		var playerHbArray:Array = new Array();
		public static var st_hbArray:Array;
		public static var bOnScreen:Number = 0;
		public static var eRemaining:Number = 0;
		var butrx:Number = 0;
		var butry:Number = 0;
		var sessionFire:Boolean = false;
		public static var csopen:Boolean = false;
		var csint:Number = 0;
		public var canSpawnEnemy:Boolean = false;
		public static var cslin:Number = 0;
		private var keyTab:uint = 9; //Uint code for TAB
		private var keyESC:uint = 27;
		var keyUpSession:Boolean = false;
		var keyDownSession:Boolean = false;
		var mainTitleScreen:titleScreen = new titleScreen;
		var pauseTitleScreen:pauseScreen = new pauseScreen;
		var pmint:int = 0;
		var btnResume:resume = new resume;
		public static var infAmmo:Boolean = false;
		private var size:uint = 48;
		public var imageArray:Array = new Array();
		public static var st_stage:Stage;
		public static var objectsPaused:Boolean = false;
		public var otherContainer:Container = new Container();
		public static var noclip = false;
		public static var mpstate:Boolean = false;
		public var mpsettingup:Boolean = true;
		var bloodArray:Array = new Array();
		public static var god:Boolean = false;
		/* ==========Write Debug Window Last========== */
		var debugwindow_mc:debugWindow = new debugWindow(fpstracker, level_mc, player_mc); //Create New DebugWindow.
		/* ==========ScreenHandler Functions========== */
		public static var screenHandlerClass:screenHandler;
		var exampleScreen:screenObject;
		var references:refHelper;
		var buttonHandlerClass:buttonHandler;
		var tempButton:buttonObject;
		var tempButtonArray:Array = new Array();
		//Barrier Handler
		public static var barrierHand:barrierHandler;
		
		// Round Variables
		public static var round:int = 1;
		var spawnDelay:int = 1;
		var roundWait:int = 20;
		public static var totalZombies:int = 0;
		public static var zombieHealth:int = 0;
		var inRound:Boolean = true;
		var zombieSpawnDelay:Boolean = false;
		var zombieSpawnDelayTimer:Timer = new Timer(spawnDelay * 1000);
		var roundWaitTimer:Timer = new Timer(roundWait * 1000);
		 
		/* ================ Huds ==================== */
		var playerHudElement:playerHud = new playerHud(550, 398)
		var engineHudElement:engineHud = new engineHud(389 , 398);
		public static var st_playerHudElement:playerHud;
		public static var st_engineHudElement:engineHud;
		public static var mHud:mainHud;
		
		public static var mp:MultiplayerClient;
		public static var mpchat:multiplayerChat;
		var updateMPTimer:Timer = new Timer(5000);
		var msgIndex:int = 0;
		
		//===============================================
		var snd_gun_shot:Sound = new pistol_fire_snd();

		/* =============Engine Constructor============= */
		public function engine() {
			//Barriers Debuging.
			barrierHand = new barrierHandler(level_mc.walls);
			//barrierHand.createBarrier(200, 150, 30, 220);
			//===========================================
			//Create The mainmenu Screen that is Created when game starts.
			//===========================================
			//===========================================
			//Create a Play Button that when clicked will switch gameState to 'inmenu'.
			tempButton = new buttonObject(new playBtn(), "ingame", stage.stageWidth / 2, 250);
			//Push the button into a Button Array.
			tempButtonArray.push(tempButton);
			//Create a Options Button that when clicked will switch gameState to 'inoptions'.
			tempButton = new buttonObject(new optionsBtn(), "inoptions", stage.stageWidth / 2, 350);
			//Push the button into a Button Array.
			tempButtonArray.push(tempButton);
			//Set References for Screen Handler.
			references = new refHelper(level_mc,playerHudElement, tempCrosshair, player_mc);
			//Create a new Screen Handler to handle screen creation.
			screenHandlerClass = new screenHandler(stage, references);
			//Make a new screen with given variables and send the buttons to it as a argument.
			exampleScreen = screenHandlerClass.makeScreen(new testScreen(), "mainmenu", 0, "thisScreen,mouse", "level,hud,crosshair,player", tempButtonArray);
			//Spawn the Screen onto Stage.
			screenHandlerClass.createScreen(exampleScreen);
			//===========================================
			//Create The Invalid Resolution Error Screen that is Created when you are
			//using a invalid resolution or scale Type.
			//===========================================
			//reset Temp Variables.
			tempButtonArray = new Array();
			//Create Retry Button.
			tempButton = new buttonObject(new retryResCheckBtn(), "mainmenu", stage.stageWidth / 2, 350);
			//Push the button into a Button Array.
			tempButtonArray.push(tempButton);
			//Make a new screen with given Variables and send the buttons to it as a argument.
			exampleScreen = screenHandlerClass.makeScreen(new invalidResolution(), "invalidresolution", 1, "thisScreen,mouse", "level,hud,crosshair,player", tempButtonArray);
			//===========================================
			//Create The Options Menu Screen that is Created when you are
			//using select the options Button.
			//===========================================
			//reset Temp Variables.
			tempButtonArray = new Array();
			//Create Back Button.
			tempButton = new buttonObject(new backBtn(), "mainmenu", stage.stageWidth / 2, 350);
			//Push the button into a Button Array.
			tempButtonArray.push(tempButton);
			//Make a new screen with given variables and send the buttons to it as a argument.
			exampleScreen = screenHandlerClass.makeScreen(new testScreen(), "inoptions", 2, "thisScreen,mouse", "level,hud,crosshair,player", tempButtonArray);
			//===========================================
			//Continue Old Code
			//===========================================
			playerHbArray.push(new healthBar(level_mc, level_mc, -25, 100, playerTarget.x, playerTarget.y));
			Security.allowDomain("http://advancedflashengine.googlecode.com");
			Security.allowDomain("http://afehandle.x10hosting.com");
			Security.allowDomain("http://ubermouse.hostoi.com");
			mapParser.parserMapFile("maps/map1/settings.ini");
			loadDecalAsset("decals/blood_pool_1.png");
			loadDecalAsset("decals/blood_pool_2.png");
			loadDecalAsset("decals/blood_pool_3.png");
			loadDecalAsset("decals/blood_pool_4.png");
			key = new KeyObject(stage);
			//Weapon Shooting
			fireTimer.addEventListener(TimerEvent.TIMER, fireFunction);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageClick);
			stage.addEventListener(MouseEvent.MOUSE_UP, onStageClickUp);
			stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
			stage.addEventListener(MouseEvent.MOUSE_OVER, mouseBackOver);
			/* =============PickupsArrayCopy======= */
			pickupsArrayRO = pickupsArray; //Set Static Pickups Array to Main Pickups Array
			powerupsArrayRO = powerupsArray;
			st_level_mc = level_mc; //Set Static Level Class to Main Level Class.
			st_player_mc = player_mc;
			st_enemyArray = enemyArray;
			st_hbArray = hbArray;
			st_playerTarget = playerTarget;
			st_pathNodeArray = pathNodeArray;
			st_stage = stage;
			st_bulletArray = bulletArray;
			st_turretArray = turretArray;
			st_playerHudElement = playerHudElement;
			st_engineHudElement = engineHudElement;
			st_spawnerArray = spawnerArray;
			addEventListener(Event.ENTER_FRAME, enterFrameHandler); //Create new Event Listener for ENTER_FRAME.
			btnResume.x = stage.stageWidth / 2;
			btnResume.y = 250;
			btnResume.addEventListener(MouseEvent.CLICK, btnResumeFunction);
			stage.addChild(kongregate); //Add Kongregate MovieClip.
			kongregate.addEventListener(KongregateEvent.COMPLETE, myMethod); //Create new Event Listener  for Kongregate.COMPLETE.
			pathnodeDebugMC.visible = false;
			pathnodeDebugMC.y = stage.stageHeight;
			player_mc.x = stage.stageWidth / 2; //Set Player X Location.
			player_mc.y = stage.stageHeight / 2; //Set Player Y Location.
			level_mc.x = stage.stageWidth / 2; //Set Level X Location.
			level_mc.y = stage.stageWidth / 2; //Set Level Y Location.
			debugwindow_mc.x = stage.stageWidth - debugwindow_mc.width - 1; //Set DebugWindow X Location.
			debugwindow_mc.y = stage.stageHeight - debugwindow_mc.height - 1; //Set DebugWindow Y Location.
			achievementNotice_mc.x = stage.stageWidth;
			achievementNotice_mc.y = stage.stageHeight;
			//achievementNotice_mc.achievements();
			myStage = this.stage; //Set Static stage to Main Stage.
			myRoot = this; //Set Static root to Main Root.
			//gameUtils.SpawnEnemy(level_mc, hbArray, enemyArray, 10, 0, 1);
			consoleMC.txtInput.addEventListener(KeyboardEvent.KEY_DOWN, ConsoleInput);
			consoleMC.txtConsole.text = "";
			level_mc.addChild(playerTarget);
			playerTarget.visible = false;
			level_mc.x = stage.stageWidth / 2; //Set Player X Location.
			level_mc.y = stage.stageHeight / 2; //Set Player Y Location.
			spawnTimer.start();
			stage.addChild(mainTitleScreen);
			stage.addChild(otherContainer);
			ai_calculateHealth();
			calculateZombieAmount();
			zombieSpawnDelayTimer.addEventListener(TimerEvent.TIMER, resetSpawnDelay);
			roundWaitTimer.addEventListener(TimerEvent.TIMER, startNewRound);
			mHud = new mainHud();
			mHud.y = stage.stageHeight;
			mHud.x = stage.stageWidth / 2;
		} //End Constructor

		function resetSpawnDelay(e:Event)
		{
			zombieSpawnDelay = false;
			zombieSpawnDelayTimer.stop();
			zombieSpawnDelayTimer.reset();
		}
		
		function ai_calculateHealth()
		{
			zombieHealth = 150 + (round * 20);
		}
		
		function calculateZombieAmount()
		{
			if (round == 1)
				totalZombies = 12; 
			else
				totalZombies = round * (Math.random() * (50 - 30) + 30);
		}
		
		function startNewRound(e:Event)
		{
			roundWaitTimer.stop();
			roundWaitTimer.reset();
			round++;
			calculateZombieAmount();
			ai_calculateHealth();
			inRound = true;
			globals.resetPowerups();
		}
		
		
		public function decalLoaderAssetDone(event:Event){
			var tempeLoader:LoaderInfo = LoaderInfo(event.target);
			imageArray.push(Bitmap(event.target.loader.content));
		}

		public function loadDecalAsset(assetLocation:String){
			var tempLoader:Loader = decalLoader.getLoader();
			tempLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, decalLoaderAssetDone);
			decalLoader.loadAsset(tempLoader, decalLoader.getRequest(assetLocation));
		}

		private function spawnBitmap(original:Bitmap, xLoc:int, yLoc:int){
			var image:Bitmap = new Bitmap(original.bitmapData.clone());
			image.x = xLoc - (size / 2);
			image.y = yLoc - (size / 2);
			level_mc.decals.addChild(image);
			bloodArray.push(image);
		}

		function newDecal(xLoc:int, yLoc:int){
			if (imageArray[1] != null){
				spawnBitmap(imageArray[Rrandom.getRandom(0, imageArray.length - 1)], xLoc, yLoc);
			}
		}
		
		public function changeLevel(levelname){
		}

		function ConsoleInput(e:KeyboardEvent){
			if (e.keyCode == 13){
				consoleParser.ParseConsoleInput(consoleMC.txtInput.text);
				consoleMC.txtInput.text = "";
			}
		}
		
		/* =============Main Engine Loop============= */
		public function enterFrameHandler(e:Event):void {
			//Round Shit
			if (totalZombies > 0 && enemyArray.length < maxAi && zombieSpawnDelay == false && inRound == true)
			{
				var spawner:Number = Math.floor(Math.random() * spawnerArray.length);
				var X:int = spawnerArray[spawner].x;
				var Y:int = spawnerArray[spawner].y;
				spawnerArray[spawner].spawnEnemy(level_mc, hbArray, enemyArray, X, Y, zombieHealth);
				totalZombies--;
				zombieSpawnDelay = true;
				zombieSpawnDelayTimer.start();
			}
			else if(totalZombies < 1 && enemyArray.length < 1)
			{
				roundWaitTimer.start();
				if(inRound == true)
					player.money *= 1.35;	
					
				inRound = false;
			}
			//End Round Shit
			
			//==========================================================================
			//Multiplayer Stuff
			//==========================================================================
			if (mpstate == true && mpsettingup == true)
			{
				//Set up Multiplayer
				var host:String = "127.0.0.1";
				mp = new MultiplayerClient(host, 5555, 5556,level_mc,stage);
				mp.start();
				mpchat = new multiplayerChat(stage);
				mpsettingup = false;
			}
			if (mpstate == true && mpsettingup == false)
			{
				//Multiplayer Loop
				mp.sendMsg("Server->Players->sendXPos->" + playerTarget.x);
				mp.sendMsg("Server->Players->sendYPos->" + playerTarget.y);
				mp.sendMsg("Server->Players->sendHealth->" + player.playerHealth);
				mp.sendMsg("Server->Players->sendRotation->" + player_mc.rotation);
			}
			//Check if there are more then 25 blood decals. If so delete some from start.
			if (bloodArray.length > 25){
				level_mc.decals.removeChild(bloodArray[0]);
				bloodArray[0].visible = false;
				bloodArray[0] = null;
				bloodArray.splice(0, 1);
			}
			playerHbArray[0].setCoords(playerTarget.x, playerTarget.y - 20);
			playerHbArray[0].setHealth(player.playerHealth);
			/*if (stage.stageHeight != 400 || stage.stageWidth != 550){
				objectsPaused = true;
				if (gameUtils.getState() != "invalidresolution"){
					gameUtils.setState("invalidresolution");
					for (var t:Number = 0; t < screenHandlerClass.currentScreens.length; t++){
						screenHandlerClass.removeScreen(screenHandlerClass.currentScreens[t]);
					}
					screenHandlerClass.createScreen(screenHandlerClass.availableScreenArray[1]);
				}
			}*/
			if (gameUtils.getState() == "pausemenu")
				objectsPaused = true;
			if (drawedGame == false && gameUtils.getState() == "ingame"){
				objectsPaused = false;
				stage.addChild(level_mc); //Add Level MovieClip.
				stage.addChild(debugwindow_mc); //Add DebugWindow MovieClip.
				stage.addChild(player_mc); //Add Player MovieClip.
				stage.addChild(achievementNotice_mc);
				stage.addChild(pathnodeDebugMC);
				//stage.addChild(playerHudElement);
				//stage.addChild(engineHudElement);
				stage.addChild(consoleMC);
				stage.addChild(tempCrosshair);
				stage.addChild(pauseTitleScreen);
				stage.addChild(btnResume);
				stage.addChild(mHud);
				//Initilize SWFProfiler.
				SWFProfiler.init(stage, this);
				btnResume.visible = false;
				mainTitleScreen.visible = false;
				pauseTitleScreen.visible = false;
				btnResume.visible = false;
				drawedGame = true;
				Mouse.hide();
			}
			if (drawedGame == true && gameUtils.getState() == "ingame") {
				mHud.visible = true;
				objectsPaused = false;
				level_mc.visible = true;
				debugwindow_mc.visible = false;
				player_mc.visible = true;
				pathnodeDebugMC.visible = false;
				playerHudElement.visible = true;
				consoleMC.visible = true;
				tempCrosshair.visible = true;
				pauseTitleScreen.visible = false;
				btnResume.visible = false;
				mainTitleScreen.visible = false;
				spawnTimer.start();
				Mouse.hide();
			}
			if (gameUtils.getState() == "mainmenu" || gameUtils.getState() == "invalidresolution" || gameUtils.getState() == "inoptions"){
				btnResume.visible = false;
				mainTitleScreen.visible = false;
				pauseTitleScreen.visible = false;
				mHud.visible = false;
			}
			if (gameUtils.getState() == "pausemenu" || gameUtils.getState() == "console" || gameUtils.getState() == "invalidresolution"){
				if (gameUtils.getState() == "pausemenu"){
					pauseTitleScreen.visible = true;
					btnResume.visible = true;
				}
				spawnTimer.stop();
				tempCrosshair.visible = false;
			}
			st_enemyArray = enemyArray;
			st_hbArray = hbArray;
			st_stage = stage;
			if (player.updateWeapon == true) {
				ammoCount = globals.findCurrentAmmoType(player.currentWeaponArray[player.currentWeapon].ammoType);
				ammoRemaining = player.currentWeaponArray[player.currentWeapon].getAmmo();
				clipSize = player.currentWeaponArray[player.currentWeapon].maxClip;
			}
			clipSize = player.weaponClipSize;
			//set hud variables
			playerHudElement.updateVariables(player.currentWeaponArray[player.currentWeapon], player.playerHealth, player.money);
			engineHudElement.updateVariables(ammoCount, clipSize, ammoRemaining);
			tempCrosshair.x = mouseX;
			tempCrosshair.y = mouseY;
			var theX:int = mouseX - player_mc.x;
			var theY:int = (mouseY - player_mc.y) * -1;
			var angle = Math.atan(theY / theX) / (Math.PI / 180);
			if (theX < 0){
				angle += 180;
			}
			if (theX >= 0 && theY < 0){
				angle += 360;
			}
			//player_mc.rotation = (angle*-1) + 90;
			tempCrosshair.x = mouseX;
			tempCrosshair.y = mouseY;
			/* ===============================
			   Calculate Trig Values
			   ===============================
			 */
			/*if (theX >= 0){
				butrx = Math.cos(Math.atan(theY / theX));
				butry = Math.sin(Math.atan((theY * -1) / theX));
			} else {
				butrx = -1 * Math.cos(Math.atan(theY / theX));
				butry = -1 * Math.sin(Math.atan((theY * -1) / theX));
			}*/
			/* ==============================
			   In Game Enemy Spawning
			 =============================== */
			if (key.isDown(keyTab) && canSpawnEnemy == true){
				canSpawnEnemy = false;
				gameUtils.SpawnEnemy(level_mc, hbArray, enemyArray, mouseX - level_mc.x, mouseY - level_mc.y + 10, 1);
			} else if (!key.isDown(keyTab)){
				canSpawnEnemy = true;
			}
			/* ==============================
			   Loop Automatic Bullets
			   ==============================
			 */
			if (player_mc.semiAutomatic == true){
				if (shooting == true && canFire == true && firedBullet == false && sessionFire == false && ammoRemaining > 0){
					if (gameUtils.getState() == "ingame"){
						gameUtils.makeBullet(player_mc, level_mc, stage, bulletArray, playerTarget.x, playerTarget.y, fireSpeed);
						snd_gun_shot.play();
						if (!infAmmo){
							ammoRemaining--;
						}
						player.currentWeaponArray[player.currentWeapon].setAmmo(ammoRemaining);
						player.updateWeapon = false;
						sessionFire = true;
						firedBullet = true;
					}
				}
			} else if (player_mc.semiAutomatic == false){
				if (shooting == true && canFire == true && firedBullet == false && ammoRemaining > 0){
					if (gameUtils.getState() == "ingame"){
						gameUtils.makeBullet(player_mc, level_mc, stage, bulletArray, playerTarget.x, playerTarget.y, fireSpeed);
						snd_gun_shot.play();
					}
					if (!infAmmo){
						ammoRemaining--;
					}
					player.currentWeaponArray[player.currentWeapon].setAmmo(ammoRemaining);
					player.updateWeapon = false;
					firedBullet = true;
				}
			}
			/* ==============================
			   Loop temp check bullets against enemys
			   ==============================
			 */
			eRemaining = 0;
			var timesCounted:Number = 0;
			if (noclip == false){
				for (var l:Number = 0; l < bulletArray.length; l++){
					if (PixelPerfectCollisionDetection.isColliding(bulletArray[l], level_mc.walls, level_mc, true)){
						bulletArray[l].killSelf();
						bulletArray.splice(l, 1);
					}
				}
			}
			shootingDelay = player_mc.weaponFireTime * 100;
			for (var i:Number = 0; i < enemyArray.length; i++){
				if (enemyArray[i].healthRem >= 1){
					eRemaining += 1;
					for (var j:Number = 0; j < bulletArray.length; j++) {
						if (globals.getDistance(bulletArray[j].x, bulletArray[j].y, enemyArray[i].x, enemyArray[i].y) < 25)
						{
							if (bulletArray[j].hitObject == false){
								if (enemyArray[i].hitTestObject(bulletArray[j]) == true){
									try {
										bulletArray[j].hitObject = true;
										bulletArray[j].killSelf();
										bulletArray.splice(j, 1);
									} catch (e:Error){
									}
									try {
										enemyArray[i].healthRem -= player_mc.weaponDamage;
									} catch (e:Error){
									}
									try {
										if (enemyArray[i].healthRem < 0){
											enemyArray[i].healthRem = 0;
										}
										hbArray[i].setHealth(enemyArray[i].healthRem);
									} catch (e:Error){
									}
								}
							}
						}
					}
				} else {
					hbArray[i].killSelf();
					hbArray.splice(i, 1);
					newDecal(enemyArray[i].x, enemyArray[i].y);
					enemyArray[i].killSelf("player");
					enemyArray[i].killed = true;
					enemyArray.splice(i, 1);
				}
			}
			if (eRemaining <= 0){
				gotoAndPlay(2);
			}
			//Check Bullets On Screen.
			bOnScreen = 0;
			for (var k:Number = 0; k < bulletArray.length; k++){
				if (bulletArray[k].alive == true){
					bOnScreen++;
				}
			}
			if (key.isDown(keyC) && csint == 0){
				csint = 1;
				if (csopen == false){
					csopen = true;
					consoleMC.y = consoleMC.height - 2;
					consoleMC.visible = true;
						//gameUtils.setState ("ingame");
				} else if (csopen == true){
					csopen = false;
					consoleMC.y = -consoleMC.height;
					consoleMC.visible = false;
					gameUtils.setState("console");
				}
			}
			if (!key.isDown(keyC)){
				csint = 0;
			}
			if (!key.isDown(keyESC)){
				pmint = 0;
			}
			if (key.isDown(keyESC) && pmint == 0){
				if (esc == 0){
					esc = 1;
				} else {
					esc = 0;
				}
				pmint = 1;
			}
			if (esc == 0){
				gameUtils.setState("pausemenu");
			} else if (drawedGame != false){
				gameUtils.setState("ingame");
			}
			if (key.isDown(key.UP) && keyUpSession == false){
				consoleParser.lNumber += 1;
				keyUpSession = true;
			}
			if (!key.isDown(key.UP)){
				keyUpSession = false;
			}
			if (key.isDown(key.DOWN) && keyDownSession == false){
				if (consoleParser.lNumber >= 0){
					consoleParser.lNumber -= 1;
				}
				keyDownSession = true;
			}
			if (!key.isDown(key.DOWN)){
				keyDownSession = false;
			}
		} //End enterFrame event

		function fireFunction(e:Event){
			if (canFire == false && player.canFire == true){
				canFire = true;
				shooting = true;
			} else if (canFire == true){
				canFire = false;
				shooting = false;
			}
			firedBullet = false;
			checkEnemies();
		}

		/* ===============================
		   Calculate Bullet Testing
		   ===============================\
		 */

		function checkEnemies(){
			for (var i:Number = 0; i < enemyArray.length; i++){
				if (enemyArray[i].killed == false){
					if (enemyArray[i].healthRem <= 0){
					}
				}
			}
		}

		function onStageClick(e:Event){
			player.mouseClicked = true;
			if (player_mc.semiAutomatic == false){
				fireTimer = null;
				fireTimer = new Timer(shootingDelay);
				fireTimer.addEventListener(TimerEvent.TIMER, fireFunction);
				if (debugOpening == false){
					if (canFire){
						fireTimer.reset();
						fireTimer.start();
					}
				}
			} else if (player_mc.semiAutomatic == true){
				fireTimer = null;
				fireTimer = new Timer(shootingDelay);
				fireTimer.addEventListener(TimerEvent.TIMER, fireFunction);
				if (debugOpening == false){
					if (canFire){
						fireTimer.reset();
						fireTimer.start();
					}
				}
			}
		}

		function onStageClickUp(e:MouseEvent){
			if (debugOpening == false){
				canFire = true;
				shooting = false;
				fireTimer.stop();
				sessionFire = false;
			}
		}

		function mouseLeave(e:Event){
			mouseActiveOnStage = false;
		}

		function mouseBackOver(e:Event){
			mouseActiveOnStage = true;
		}

		function btnResumeFunction(e:MouseEvent){
			gameUtils.setState("ingame");
			esc = 1;
		}

		/* =============Kongregate Services Available============= */
		function myMethod(e:KongregateEvent):void {
			//Testing Achivements...
			kongregate.stats.submit("Loaded Game", 1); //Started Game Achivement.
			//MochiAd.showPreGameAd({clip:otherContainer, id:"13fdf38cea0e70cf", res:"550x400", background:0x0F0E0E, color:0xF0EBE4, outline:0x9E9893});
		}
	} //End class
} //End package